using Microsoft.EntityFrameworkCore;
using MediPlatform.Domain.Order;
using MediPlatform.Infeartructure;
using MediPlatform.Read.Api.Models;
using MediPlatform.ErrorCode;

namespace MediPlatform.Read.Api.Services
{
    public class PrescriptionOrderService
    {
        private readonly MyDbContext _context;
        private readonly ILogger<PrescriptionOrderService> _logger;

        public PrescriptionOrderService(MyDbContext context, ILogger<PrescriptionOrderService> logger)
        {
            _context = context;
            _logger = logger;
        }

        public async Task<PrescriptionOrderPagedResponse> GetPagedListAsync(PrescriptionOrderQueryRequest request)
        {
            try
            {
                _logger.LogInformation("开始查询处方流转订单列表，参数：{@Request}", request);

                // 检查数据库连接
                if (!_context.Database.CanConnect())
                {
                    _logger.LogError("无法连接到数据库");
                    throw new InvalidOperationException("数据库连接失败");
                }

                var query = _context.PrescriptionOrder
                    .Include(po => po.Prescription)
                    .Include(po => po.Patient)
                    .Include(po => po.Doctor)
                    .AsQueryable();

                // 应用筛选条件
                if (!string.IsNullOrWhiteSpace(request.PatientNameOrPhone))
                {
                    var searchTerm = request.PatientNameOrPhone.Trim();
                    query = query.Where(po => 
                        (po.Patient != null && po.Patient.Username != null && po.Patient.Username.Contains(searchTerm)) ||
                        (po.Patient != null && po.Patient.PhoneNumber != null && po.Patient.PhoneNumber.Contains(searchTerm))
                    );
                }

                if (request.StartTime.HasValue)
                {
                    query = query.Where(po => po.CreatedAt >= request.StartTime.Value);
                }

                if (request.EndTime.HasValue)
                {
                    var endTime = request.EndTime.Value.AddDays(1).AddSeconds(-1);
                    query = query.Where(po => po.CreatedAt <= endTime);
                }

                // 根据状态筛选
                if (request.Status.HasValue)
                {
                    switch (request.Status.Value)
                    {
                        case 0: // 待支付
                            query = query.Where(po => po.PaymentStatus == 0);
                            break;
                        case 1: // 已完成
                            query = query.Where(po => po.Status == 6 && po.PaymentStatus == 1); // 已送达且已支付
                            break;
                        case 2: // 已失效
                            query = query.Where(po => po.Status == 7 || po.PaymentStatus == 2); // 已取消或已退款
                            break;
                    }
                }

                var totalCount = await query.CountAsync();

                var items = await query
                    .OrderByDescending(po => po.CreatedAt)
                    .Skip((request.PageIndex - 1) * request.PageSize)
                    .Take(request.PageSize)
                    .Select(po => new PrescriptionOrderListItem
                    {
                        Id = po.Id,
                        OrderNo = po.OrderNo,
                        PrescriptionNo = po.Prescription != null ? po.Prescription.PrescriptionNo : null,
                        PatientName = po.Patient != null ? po.Patient.Username : null,
                        PatientPhone = po.Patient != null ? po.Patient.PhoneNumber : null,
                        DepartmentName = GetDepartmentName(po.Prescription != null ? po.Prescription.DepartmentId : null),
                        DoctorName = po.Doctor != null ? po.Doctor.Username : null,
                        PaymentAmount = po.PaymentAmount,
                        Status = GetOrderStatus(po.Status, po.PaymentStatus),
                        StatusText = GetOrderStatusText(po.Status, po.PaymentStatus),
                        PrescriptionStatus = po.Prescription != null ? po.Prescription.Status : null,
                        PrescriptionStatusText = GetPrescriptionStatusText(po.Prescription != null ? po.Prescription.Status : null),
                        PurchaseMethod = GetPurchaseMethod(po.Status),
                        DispensingStatus = GetDispensingStatus(po.Status),
                        CreatedAt = po.CreatedAt
                    })
                    .ToListAsync();

                var result = new PrescriptionOrderPagedResponse
                {
                    Items = items,
                    TotalCount = totalCount,
                    TotalPages = (int)Math.Ceiling((double)totalCount / request.PageSize),
                    CurrentPage = request.PageIndex,
                    PageSize = request.PageSize
                };

                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取处方流转订单分页列表失败");
                throw;
            }
        }

        public async Task<PrescriptionOrderDetailResponse?> GetDetailAsync(long id)
        {
            try
            {
                _logger.LogInformation("开始查询处方流转订单详情，订单ID：{OrderId}", id);

                var order = await _context.PrescriptionOrder
                    .Include(po => po.Prescription)
                    .Include(po => po.Patient)
                    .Include(po => po.Doctor)
                    .FirstOrDefaultAsync(po => po.Id == id);

                if (order == null)
                {
                    _logger.LogWarning("未找到订单，订单ID：{OrderId}", id);
                    return null;
                }

                // 获取流转日志
                var logs = await _context.PrescriptionLog
                    .Where(pl => pl.OrderId == id)
                    .OrderByDescending(pl => pl.OperateTime)
                    .Select(pl => new PrescriptionLogInfo
                    {
                        Id = pl.Id,
                        OrderId = pl.OrderId,
                        Status = pl.Status,
                        StatusText = GetLogStatusText(pl.Status),
                        OperatorId = pl.OperatorId,
                        OperatorName = GetOperatorName(pl.OperatorId),
                        OperateTime = pl.OperateTime,
                        Remark = pl.Remark,
                        CreatedAt = pl.CreatedAt
                    })
                    .ToListAsync();

                var result = new PrescriptionOrderDetailResponse
                {
                    OrderInfo = new PrescriptionOrderInfo
                    {
                        Id = order.Id,
                        OrderNo = order.OrderNo,
                        PrescriptionId = order.PrescriptionId,
                        PatientId = order.PatientId,
                        PatientName = order.Patient != null ? order.Patient.Username : null,
                        PatientPhone = order.Patient != null ? order.Patient.PhoneNumber : null,
                        DoctorId = order.DoctorId,
                        DoctorName = order.Doctor != null ? order.Doctor.Username : null,
                        PharmacyId = order.PharmacyId,
                        PharmacyName = GetPharmacyName(order.PharmacyId),
                        Status = order.Status,
                        StatusText = GetOrderStatusText(order.Status, order.PaymentStatus),
                        PaymentStatus = order.PaymentStatus,
                        PaymentStatusText = GetPaymentStatusText(order.PaymentStatus),
                        PaymentAmount = order.PaymentAmount,
                        DiscountAmount = order.DiscountAmount,
                        PaymentMethod = order.PaymentMethod,
                        PaymentTime = order.PaymentTime,
                        DeliveryAddress = order.DeliveryAddress,
                        LogisticsCompany = order.LogisticsCompany,
                        TrackingNumber = order.TrackingNumber,
                        SignTime = order.SignTime,
                        CreatedAt = order.CreatedAt,
                        UpdatedAt = order.UpdatedAt
                    },
                    PrescriptionInfo = new PrescriptionInfo
                    {
                        Id = order.Prescription?.Id,
                        PrescriptionNo = order.Prescription?.PrescriptionNo,
                        PatientId = order.Prescription?.PatientId,
                        DoctorId = order.Prescription?.DoctorId,
                        HospitalId = order.Prescription?.HospitalId,
                        HospitalName = GetHospitalName(order.Prescription?.HospitalId),
                        DepartmentId = order.Prescription?.DepartmentId,
                        DepartmentName = GetDepartmentName(order.Prescription?.DepartmentId),
                        Diagnosis = order.Prescription?.Diagnosis,
                        Status = order.Prescription?.Status,
                        StatusText = GetPrescriptionStatusText(order.Prescription?.Status),
                        ValidUntil = order.Prescription?.ValidUntil,
                        CreatedAt = order.Prescription?.CreatedAt
                    },
                    Logs = logs
                };

                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取处方流转订单详情失败，订单ID：{OrderId}", id);
                throw;
            }
        }

        public async Task<PrescriptionOrderStatisticsResponse> GetStatisticsAsync()
        {
            try
            {
                _logger.LogInformation("开始获取处方流转订单统计信息");

                var totalCount = await _context.PrescriptionOrder.CountAsync();
                var pendingPaymentCount = await _context.PrescriptionOrder.CountAsync(po => po.PaymentStatus == 0);
                var completedCount = await _context.PrescriptionOrder.CountAsync(po => po.Status == 6 && po.PaymentStatus == 1);
                var invalidatedCount = await _context.PrescriptionOrder.CountAsync(po => po.Status == 7 || po.PaymentStatus == 2);

                return new PrescriptionOrderStatisticsResponse
                {
                    TotalCount = totalCount,
                    PendingPaymentCount = pendingPaymentCount,
                    CompletedCount = completedCount,
                    InvalidatedCount = invalidatedCount
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取处方流转订单统计信息失败");
                throw;
            }
        }

        #region 私有方法

        /// <summary>
        /// 获取订单状态
        /// </summary>
        private static int GetOrderStatus(int? status, int? paymentStatus)
        {
            if (paymentStatus == 0) return 0; // 待支付
            if (status == 6 && paymentStatus == 1) return 1; // 已完成
            if (status == 7 || paymentStatus == 2) return 2; // 已失效
            return 0; // 默认待支付
        }

        /// <summary>
        /// 获取订单状态文本
        /// </summary>
        private static string GetOrderStatusText(int? status, int? paymentStatus)
        {
            if (paymentStatus == 0) return "待支付";
            if (status == 6 && paymentStatus == 1) return "已完成";
            if (status == 7 || paymentStatus == 2) return "已失效";
            return "待支付";
        }

        /// <summary>
        /// 获取处方状态文本
        /// </summary>
        private static string GetPrescriptionStatusText(int? status)
        {
            return status switch
            {
                1 => "有效",
                2 => "已使用",
                3 => "已过期",
                4 => "已作废",
                _ => "审核通过"
            };
        }

        /// <summary>
        /// 获取支付状态文本
        /// </summary>
        private static string GetPaymentStatusText(int? status)
        {
            return status switch
            {
                0 => "待支付",
                1 => "已支付",
                2 => "已退款",
                _ => "待支付"
            };
        }

        /// <summary>
        /// 获取日志状态文本
        /// </summary>
        private static string GetLogStatusText(int? status)
        {
            return status switch
            {
                0 => "待发送",
                1 => "已发送",
                2 => "药店已接收",
                3 => "药店已审核",
                4 => "已配药",
                5 => "已取药",
                6 => "已送达",
                7 => "已取消",
                _ => "未知状态"
            };
        }

        /// <summary>
        /// 获取购药方式
        /// </summary>
        private static string GetPurchaseMethod(int? status)
        {
            if (status == null) return "-";
            if (status >= 2 && status <= 5) return "药店购药";
            if (status == 6) return "在线配送";
            return "-";
        }

        /// <summary>
        /// 获取发药状态
        /// </summary>
        private static string GetDispensingStatus(int? status)
        {
            if (status == null) return "-";
            if (status >= 4 && status <= 6) return "已核准发药";
            if (status < 4) return "未核准发药";
            return "-";
        }

        /// <summary>
        /// 获取科室名称（模拟数据）
        /// </summary>
        private static string GetDepartmentName(long? departmentId)
        {
            // 这里应该从数据库查询，暂时返回模拟数据
            return departmentId switch
            {
                1 => "内科",
                2 => "外科",
                3 => "儿科",
                4 => "妇产科",
                5 => "眼科",
                _ => "内科"
            };
        }

        /// <summary>
        /// 获取医院名称（模拟数据）
        /// </summary>
        private static string GetHospitalName(long? hospitalId)
        {
            // 这里应该从数据库查询，暂时返回模拟数据
            return hospitalId switch
            {
                1 => "第一人民医院",
                2 => "第二人民医院",
                3 => "中医院",
                _ => "第一人民医院"
            };
        }

        /// <summary>
        /// 获取药店名称（模拟数据）
        /// </summary>
        private static string GetPharmacyName(long? pharmacyId)
        {
            // 这里应该从数据库查询，暂时返回模拟数据
            return pharmacyId switch
            {
                1 => "同仁堂药店",
                2 => "老百姓大药房",
                3 => "海王星辰药店",
                _ => "同仁堂药店"
            };
        }

        /// <summary>
        /// 获取操作人员姓名（模拟数据）
        /// </summary>
        private static string GetOperatorName(long? operatorId)
        {
            // 这里应该从数据库查询，暂时返回模拟数据
            return operatorId switch
            {
                1 => "张三",
                2 => "李四",
                3 => "王五",
                _ => "系统管理员"
            };
        }

        #endregion
    }
} 